/**
 * 
 */
package model.core.torneo.calendario;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import model.core.torneo.Gara;
import model.core.utente.GiocatoreInterface;

/**
 * @author Giuseppe Fusco (fusgius@gmail.com)
 *
 */
public class GironeItaliano extends AbstractCalendarioGenerator {

	private static GironeItaliano instance;
	
	private GironeItaliano(){
		
	}
	
	public static GironeItaliano getInstance() {
		if(instance==null)
			instance = new GironeItaliano();
		return instance;
	}
	
	/* (non-Javadoc)
	 * @see model.core.torneo.calendario.CalendarioGenerator#generate(java.util.List)
	 */
	@Override
	public List<Gara> generate(List<? extends GiocatoreInterface> giocatori) {
		// TODO Auto-generated method stub
		
		List<Gara> gare_andata = new ArrayList<Gara>();
		List<Gara> gare_ritorno = new ArrayList<Gara>();
		
		if(giocatori.size() % 2!=0)
			giocatori.add(null);
		int num_g = giocatori.size();
		int days = num_g-1;
		GiocatoreInterface[] in = new GiocatoreInterface[num_g/2];
		GiocatoreInterface[] out = new GiocatoreInterface[num_g/2];
		for(int i=0; i<num_g/2; i++){
			in[i] = giocatori.get(i);
			out[i] = giocatori.get(num_g-1-i);
		}
		
		// genera il girone di andata
		for(int i=0; i<days; i++){
			// alterna le partite in casa e fuori
			if(i%2==0){
				for(int j=0; j<num_g/2; j++){
					Gara gara = new Gara();
					gara.addGiocatore(out[j]);
					gara.addGiocatore(in[j]);
					gare_andata.add(gara);
					
					Gara gara1 = new Gara();
					gara1.addGiocatore(in[j]);
					gara1.addGiocatore(out[j]);
					gare_ritorno.add(gara1);
				}
			}else{
				for(int j=0; j<num_g/2; j++){
					Gara gara = new Gara();
					gara.addGiocatore(in[j]);
					gara.addGiocatore(out[j]);
					gare_andata.add(gara);
					
					Gara gara1 = new Gara();
					gara1.addGiocatore(out[j]);
					gara1.addGiocatore(in[j]);
					gare_ritorno.add(gara1);
				}
			}
			List<GiocatoreInterface> in_list = Arrays.asList(in);
			List<GiocatoreInterface> out_list = Arrays.asList(out);
			
			// Ruota in gli elementi delle liste, tenendo fisso il primo elemento
			Collections.rotate(in_list.subList(1, in_list.size()), -1);
			Collections.rotate(out_list.subList(1, out_list.size()), -1);
			for(int k=1; k<in_list.size(); k++){
				in[k] = in_list.get(k);
				out[k] = out_list.get(k);
			}
			
			// Salva l'elemento fisso
			GiocatoreInterface pivot = in[0];
			
			out_list = Arrays.asList(out);
			
			//  sposta in avanti gli elementi di "trasferta" inserendo 
	        //   all'inizio l'elemento casa[1] e salva l'elemento uscente in "riporto"
			Collections.rotate(out_list, 1);
			for(int z=0; z<out_list.size(); z++)
				out[z] = out_list.get(z);
			GiocatoreInterface riporto = out[0];
			out[0] = in[1];

			in_list = Arrays.asList(in);
			Collections.rotate(in_list, -1);
			for(int z=0; z<in_list.size(); z++)
				in[z] = in_list.get(z);
			in[in.length-1] = riporto;
			
			// ripristina l'elemento fisso
			in[0] = pivot;
		}
		
		// genera il girone di ritorno
		List<Gara> gare_compl = new ArrayList<Gara>();
		for(Gara g: gare_andata)
			gare_compl.add(g);
		for(Gara g: gare_ritorno)
			gare_compl.add(g);
		return gare_compl;
	}
  
}
